<template>
  <div ref="mapContainer" class="map-heatmap"></div>
</template>

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount } from 'vue'
import Map from 'ol/Map'
import View from 'ol/View'
import { fromLonLat } from 'ol/proj'
import HeatmapLayer from 'ol/layer/Heatmap'
import VectorSource from 'ol/source/Vector'
import Feature from 'ol/Feature'
import Point from 'ol/geom/Point'
import TileLayer from 'ol/layer/Tile'
import XYZ from 'ol/source/XYZ'

const mapContainer = ref<HTMLDivElement | null>(null)
let map: Map | null = null

/**
 * 生成随机热力点数据（以北京为中心，半径约500km）
 * @param count 点的数量
 * @returns Feature<Point>[]
 */
function generateRandomPoints(count = 500) {
  const features = []
  const center = [116.397, 39.917] // 北京天安门经纬度
  for (let i = 0; i < count; i++) {
    const angle = Math.random() * 2 * Math.PI // 随机角度
    const radius = Math.random() * 5 // 半径最大约5度经纬度（约500km）
    // 极坐标转经纬度
    const lon = center[0] + Math.cos(angle) * radius
    const lat = center[1] + Math.sin(angle) * radius
    // 创建带有权重的点要素
    const feature = new Feature({
      geometry: new Point(fromLonLat([lon, lat])),
      weight: Math.random() // 热力强度（0~1）
    })
    features.push(feature)
  }
  return features
}

onMounted(() => {
  // 创建热力点数据源
  const vectorSource = new VectorSource({
    features: generateRandomPoints(1000)
  })

  // 创建热力图图层
  const heatmapLayer = new HeatmapLayer({
    source: vectorSource,
    blur: 20,         // 模糊半径
    radius: 15,       // 点半径
    weight: 'weight', // 使用 feature 的 weight 属性
    opacity: 0.7      // 保证底图可见
  })

  // 创建底图（可用 OSM 或高德，开发环境推荐 OSM）
  const baseLayer = new TileLayer({
    source: new XYZ({
      url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}'
    })
  })

  // 初始化地图
  map = new Map({
    target: mapContainer.value as HTMLDivElement,
    layers: [baseLayer, heatmapLayer], // 先底图后热力图
    view: new View({
      center: fromLonLat([116.397, 39.917]), // 北京为中心
      zoom: 7,      // 缩小初始缩放，适合大范围
      minZoom: 3,
      maxZoom: 18
    })
  })
})

onBeforeUnmount(() => {
  // 组件卸载时销毁地图实例
  if (map) {
    map.setTarget(undefined)
    map = null
  }
})
</script>

<script lang="ts">
export default {
  name: 'HeatmapMap'
}
</script>

<style scoped>
.map-heatmap {
  width: 100%;
  height: 100%;
  background: #222;
}
</style> 